package com.sky.config;

import com.sky.dto.ResourceRoleDTO;
import com.sky.entity.Employee;
import com.sky.entity.SysRole;
import com.sky.entity.User;
import com.sky.filter.DynamicSecurityService;
import com.sky.mapper.SysResourceMapper;
import com.sky.service.EmployeeService;
import com.sky.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 1. 查询出资源对应的角色
 * 2. 后台服务配置动态权限
 * @author 陈烨庆
 * @version 1.0
 */
@Configuration
@EnableWebSecurity
public class ServerSecurityConfig extends SecurityConfig {

    @Autowired
    private EmployeeService employeeService;

    @Autowired
    private UserService userService;

    @Autowired
    private SysResourceMapper sysResourceMapper;

    @Bean("employeeUserDetailsService")
    public UserDetailsService userDetailsService() {
        return username -> {
            Employee employee = employeeService.loadUserByUsername(username);
            return employee;
        };
    }

    @Bean("userUserDetailsService")
    public UserDetailsService userService() {
        return username -> {
            User user = userService.loadUserByOpenId(username);
            return user;
        };
    }

    /**
     * 为 SpringSecurity 配置的资源角色信息（静态）
     * @return
     */
    // @Bean
    public SecurityResourceRoleSource securityResourceRoleSource() {
        return () -> {
            // 调用业务逻辑类查询资源对应角色信息
            HashMap<String, List<String>> map = new HashMap<>();
            List<ResourceRoleDTO> list = sysResourceMapper.getAllResourceRole();
            for (ResourceRoleDTO resourceRoleDTO : list) {
                List<String> roleList = resourceRoleDTO.getRoleList().stream()
                        .map(SysRole::getName)
                        .collect(Collectors.toList());
                map.put(resourceRoleDTO.getUrl(), roleList);
            }
            return map;
        };
    }

    /**
     * 为 SpringSecurity 配置的资源角色信息（静态）
     * @return
     */
    @Bean("dynamicSecurityService")
    public DynamicSecurityService dynamicSecurityService() {
        return () -> {
            // 调用业务逻辑类查询资源对应角色信息
            Map<RequestMatcher, List<ConfigAttribute>> map = new HashMap<>();

            List<ResourceRoleDTO> list = sysResourceMapper.getAllResourceRole();
            for (ResourceRoleDTO resource : list) {
                // 通配符匹配器
                map.put(new AntPathRequestMatcher(resource.getUrl()),
                        // 所有角色信息
                        resource.getRoleList().stream()
                                .map(role -> new org.springframework.security.access.SecurityConfig(role.getName()))
                                .collect(Collectors.toList())
                        );
            }
            return map;
        };
    }

}